<template>
  <div class="dashboard-container">
    <div class="header-section">
      <div class="title-section">
        <h2>数据仪表盘</h2>
        <span class="subtitle">实时数据分析与监控</span>
      </div>
      <div class="date-picker-section">
        <el-date-picker
          v-model="dateRange"
          type="daterange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          size="default"
          value-format="YYYY-MM-DD"
          @change="handleDateRangeChange"
          :shortcuts="dateShortcuts"
          :default-value="getLastSevenDays()"
          class="custom-date-picker"
          :clearable="false"
        />
      </div>
    </div>

    <!-- Top Stats Cards -->
    <div class="stats-cards">
      <div class="stat-card" v-for="(stat, index) in topStats" :key="index">
        <div class="stat-icon">
          <el-icon>
            <component :is="stat.icon"></component>
          </el-icon>
        </div>
        <div class="stat-content">
          <h3 class="stat-title">{{ stat.title }}</h3>
          <div class="stat-value" ref="statValues">{{ stat.value }}</div>
          <div class="stat-description">{{ stat.description }}</div>
        </div>
      </div>
    </div>

    <!-- Middle Section -->
    <div class="middle-section">
      <!-- Left Column -->
      <div class="chart-card">
        <div class="chart-header">
          <h3>报名活动类别分布</h3>
        </div>
        <div class="chart" ref="activityCategoriesChart"></div>
      </div>

      <div class="chart-card">
        <div class="chart-header">
          <h3>报名趋势</h3>
        </div>
        <div class="chart" ref="activityTrendChart"></div>
      </div>

      <!-- Right Column -->
      <div class="chart-card">
        <div class="chart-header">
          <h3>热门活动  </h3>
        </div>
        <div class="chart" ref="topActivitiesChart"></div>
      </div>

      <div class="chart-card">
        <div class="chart-header">
          <h3>用户增长趋势</h3>
        </div>
        <div class="chart" ref="userGrowthChart"></div>
      </div>
    </div>
    <!-- Bottom Section -->
    <div class="bottom-section">
      <div class="chart-card">
        <div class="chart-header">
          <h3>活动总数统计</h3>
        </div>
        <div class="chart" ref="totalActivitiesChart"></div>
      </div>
      <div class="chart-card">
        <div class="chart-header">
          <h3>活动参与情况统计</h3>
        </div>
        <div class="chart" ref="activitySignupChart"></div>
      </div>
      <div class="chart-card">
        <div class="chart-header">
          <h3>网站流量统计</h3>
        </div>
        <div class="chart" ref="visitStatsChart"></div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, markRaw, onMounted, onUnmounted, nextTick } from "vue";
import * as echarts from "echarts";
import { getOverview } from "@/apis/overview";
import { opLogPage } from "@/apis/admin/opLog";
import { ElMessage } from "element-plus";
import {
  User,
  Calendar,
  Star,
  ChatLineRound,
  Grid,
} from "@element-plus/icons-vue";

// Data refs
const map = ref({});

// 获取最近7天的日期范围
const getLastSevenDays = () => {
  const end = new Date();
  const start = new Date();
  start.setTime(start.getTime() - 3600 * 1000 * 24 * 6); // 减去6天，加上今天，共7天
  return [start.toISOString().split("T")[0], end.toISOString().split("T")[0]];
};
const dateRange = ref(getLastSevenDays());
const refreshInterval = ref(null);

// 添加日期快捷选项
const dateShortcuts = [
  {
    text: "最近7天",
    value: () => getLastSevenDays(),
  },
  {
    text: "最近30天",
    value: () => {
      const end = new Date();
      const start = new Date();
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
      return [start, end];
    },
  },
  {
    text: "本月",
    value: () => {
      const end = new Date();
      const start = new Date(end.getFullYear(), end.getMonth(), 1);
      return [start, end];
    },
  },
];

// Chart refs
const activityCategoriesChart = ref(null);
const activityTrendChart = ref(null);
const topActivitiesChart = ref(null);
const userGrowthChart = ref(null);
const totalActivitiesChart = ref(null);
const activitySignupChart = ref(null);
const visitStatsChart = ref(null);

// Chart instances
const chartInstances = reactive({
  categoryChart: null,
  activityTrendChart: null,
  topActivitiesChart: null,
  userGrowthChart: null,
  totalActivitiesChart: null,
  activitySignupChart: null,
  visitStatsChart: null,
});

// Top stats data
const topStats = ref([
  {
    title: "总用户数",
    value: 0,
    icon: "User",
    description: "注册成功的用户总数",
  },
  {
    title: "活动总数",
    value: 0,
    icon: "Calendar",
    description: "所有已发布的活动总量",
  },
  {
    title: "报名总数",
    value: 0,
    icon: "Grid",
    description: "所有活动累计报名次数",
  },
  {
    title: "评论总数",
    value: 0,
    icon: "ChatLineRound",
    description: "用户发布的评论总量",
  },
]);

// 请求数据
const fetchData = async (startDate = null, endDate = null) => {
  try {
    console.log("Fetching data with dates:", startDate, endDate);

    // 如果没有提供日期，使用默认的最近7天
    if (!startDate || !endDate) {
      const [defaultStart, defaultEnd] = getLastSevenDays();
      startDate = defaultStart.toISOString().split("T")[0];
      endDate = defaultEnd.toISOString().split("T")[0];
    }

    const params = ref({});
    params.value.startTime = startDate;
    params.value.endTime = endDate;

    // 调用API时传入参数
    const response = await getOverview(params.value);
    map.value = response.data;
    updateTopStats();

    // Initialize charts after data is fetched
    await nextTick();
    initCharts(params);
  } catch (error) {
    ElMessage.error("获取数据失败，请稍后重试");
  }
};

// Handle time range changes
const handleDateRangeChange = (val) => {
  console.log("Selected date range:", val);

  if (val && val.length === 2) {
    // 有效的日期范围
    const [startDate, endDate] = val;
    // 根据选择的日期范围重新加载数据
    fetchData(startDate, endDate);
  } else {
    // 用户清除了日期范围，加载默认数据（最近7天）
    const [defaultStart, defaultEnd] = getLastSevenDays();
    dateRange.value = [defaultStart, defaultEnd];
    fetchData(
      defaultStart.toISOString().split("T")[0],
      defaultEnd.toISOString().split("T")[0]
    );
  }
};

const updateTopStats = () => {
  topStats.value[0].value = map.value.totalUsers || 0;
  topStats.value[1].value = map.value.totalActivities || 0;
  topStats.value[2].value = map.value.totalActivitiesSignup || 0;
  topStats.value[3].value = map.value.totalComments || 0;
};

// Initialize all charts
const initCharts = (params = {}) => {
  // Dispose existing charts first to prevent memory leaks
  disposeCharts();

  // 等待下一个DOM更新周期
  nextTick(() => {
    // 使用params参数进行图表初始化
    initTotalActivitiesChart(params);
    initActivitiesSignupChart(params);
    initVisitStatsChart(params);
    initCategoryCharts(params);
    initActivityTrendChart(params);
    initTopActivitiesChart(params);
    initUserGrowthChart(params);

    // Add resize event listener
    window.addEventListener("resize", handleResize);
  });
};

// Handle window resize
const handleResize = () => {
  // Resize all chart instances
  Object.values(chartInstances).forEach((chart) => {
    chart && chart.resize();
  });
};

// 删除所有图表实例
const disposeCharts = () => {
  Object.values(chartInstances).forEach((chart) => {
    chart && chart.dispose();
  });
};

// 活动类别所占比例
const initCategoryCharts = () => {
  if (!activityCategoriesChart.value) return;

  // 检测数据是否可用
  if (!map.value.categories || !Array.isArray(map.value.categories)) {
    console.warn("Categories data not available");
    return;
  }

  chartInstances.categoryChart = markRaw(
    echarts.init(activityCategoriesChart.value)
  );
  const categoryOption = {
    title: {
      text: "活动类别占比",
      left: "center",
      textStyle: {
        color: "#333",
        fontWeight: "normal",
      },
    },
    tooltip: {
      trigger: "item",
      formatter: "{a} <br/>{b}: {c} ({d}%)",
    },
    legend: {
      orient: "vertical",
      left: "left",
      data: map.value.categories.map((item) => item.categoryName) || [],
    },
    series: [
      {
        name: "活动类别",
        type: "pie",
        radius: ["40%", "70%"],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 10,
          borderColor: "#fff",
          borderWidth: 2,
        },
        label: {
          show: false,
          position: "center",
        },
        emphasis: {
          label: {
            show: true,
            fontSize: "18",
            fontWeight: "bold",
          },
        },
        labelLine: {
          show: false,
        },
        data:
          map.value.categories.map((item) => ({
            value: item.categoryNum,
            name: item.categoryName,
          })) || [],
      },
    ],
  };
  chartInstances.categoryChart.setOption(categoryOption);
};

// 报名趋势 近 6 个月
const initActivityTrendChart = () => {
  if (!activityTrendChart.value) return;

  // 检测数据是否可用
  if (!map.value.activityTrend || !Array.isArray(map.value.activityTrend)) {
    console.warn("Activity trend data not available");
    return;
  }

  chartInstances.activityTrendChart = markRaw(
    echarts.init(activityTrendChart.value)
  );
  const option = {
    tooltip: { trigger: "axis" },
    legend: { data: ["报名数量"] },
    xAxis: {
      type: "category",
      data: map.value.activityTrend?.map((item) => item.day) || [],
    },
    yAxis: { type: "value" },
    series: [
      {
        name: "报名数量",
        type: "line",
        smooth: true,
        data: map.value.activityTrend?.map((item) => item.count) || [],
        areaStyle: { opacity: 0.3 },
      },
    ],
  };
  chartInstances.activityTrendChart.setOption(option);
};

// 热门活动  
const initTopActivitiesChart = () => {
  if (!topActivitiesChart.value) return;
  // 检测数据是否可用
  if (
    !map.value.popularActivities ||
    !Array.isArray(map.value.popularActivities)
  ) {
    console.warn("Popular activities data not available");
    return;
  }

  chartInstances.topActivitiesChart = markRaw(
    echarts.init(topActivitiesChart.value)
  );
  const hasData = map.value.popularActivities?.length > 0;
  const topActivitiesOption = {
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow",
      },
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true,
    },
    xAxis: {
      type: "value",
      splitLine: {
        lineStyle: {
          type: "dashed",
          color: "#E5E7EB"
        }
      }
    },
    yAxis: {
      type: "category",
      data: hasData ? map.value.popularActivities.map(item => item.title) : ["暂无数据"],
      axisLabel: {
        color: "#666",
        fontSize: 12
      }
    },
    series: [
      {
        name: "报名人数",
        type: "bar",
        data: hasData ? map.value.popularActivities.map(item => ({
          value: item.count,
          itemStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
              { offset: 0, color: '#83bff6' },
              { offset: 0.5, color: '#188df0' },
              { offset: 1, color: '#188df0' }
            ])
          }
        })) : [
          {
            value: 0,
            itemStyle: {
              color: '#E5E7EB'
            }
          }
        ],
        barWidth: '60%',
        emphasis: {
          itemStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
              { offset: 0, color: '#66a6e5' },
              { offset: 0.7, color: '#1677d9' },
              { offset: 1, color: '#1677d9' }
            ])
          }
        }
      }
    ],
  };
  chartInstances.topActivitiesChart.setOption(topActivitiesOption);
};

// 用户增长趋势
const initUserGrowthChart = () => {
  if (!userGrowthChart.value) return;

  // 检测数据是否可用
  if (!map.value.userGrowth || !Array.isArray(map.value.userGrowth)) {
    console.warn("User growth data not available");
    return;
  }

  chartInstances.userGrowthChart = markRaw(echarts.init(userGrowthChart.value));
  const option = {
    tooltip: { trigger: "axis" },
    xAxis: {
      type: "category",
      data: map.value.userGrowth?.map((item) => item.day) || [],
    },
    yAxis: { type: "value" },
    series: [
      {
        name: "新增用户",
        type: "line",
        smooth: true,
        data: map.value.userGrowth?.map((item) => item.count) || [],
        markArea: {
          itemStyle: { color: "rgba(255, 173, 177, 0.4)" },
          data: [[{ xAxis: "0" }, { xAxis: "7" }]],
        },
      },
    ],
  };
  chartInstances.userGrowthChart.setOption(option);
};

// 活动总数、活动新增
const initTotalActivitiesChart = () => {
  if (!totalActivitiesChart.value) return;

  chartInstances.totalActivitiesChart = markRaw(
    echarts.init(totalActivitiesChart.value)
  );
  const option = {
    title: {
      show: false,
    },
    tooltip: {},
    legend: {
      data: ["数量"],
    },
    xAxis: {
      data: ["活动总数", "当前活动总数"],
    },
    yAxis: {},
    series: [
      {
        name: "数量",
        type: "bar",
        data: [map.value.totalActivities || 0, map.value.sevenDaysNew || 0],
      },
    ],
  };
  chartInstances.totalActivitiesChart.setOption(option);
};

const initActivitiesSignupChart = () => {
  if (!activitySignupChart.value) return;

  chartInstances.activitySignupChart = markRaw(
    echarts.init(activitySignupChart.value)
  );
  const option = {
    title: {
      show: false,
    },
    tooltip: {},
    legend: {
      data: ["活动数量", "人数"],
    },
    xAxis: {
      data: ["未参加", "已参加", "取消报名"],
    },
    yAxis: {},
    series: [
      {
        name: "活动数量",
        type: "bar",
        data: [
          map.value.noParticipating || 0,
          map.value.participated || 0,
          map.value.cancelSignUp || 0,
        ],
      },
      {
        name: "人数",
        type: "bar",
        data: [
          map.value.noParticipatingPopulation || 0,
          map.value.participatedPopulation || 0,
          map.value.cancelSignUppPopulation || 0,
        ],
      },
    ],
  };
  chartInstances.activitySignupChart.setOption(option);
};

const initVisitStatsChart = () => {
  if (!visitStatsChart.value) return;
  if (!map.value.visitList || !Array.isArray(map.value.visitList)) {
    console.warn("网站流量不可用");
    return;
  }

  chartInstances.visitStatsChart = markRaw(echarts.init(visitStatsChart.value));
  const option = {
    title: {
      show: false,
    },
    tooltip: {
      trigger: "axis",
    },
    legend: {
      data: ["PV", "UV"],
    },
    xAxis: {
      type: "category",
      data: map.value.visitList.map((item) => item.day),
    },
    yAxis: {},
    series: [
      {
        name: "PV",
        type: "line",
        data: map.value.visitList.map((item) => item.pv),
      },
      {
        name: "UV",
        type: "line",
        data: map.value.visitList.map((item) => item.uv),
      },
    ],
  };
  chartInstances.visitStatsChart.setOption(option);
};

// 五分钟自动刷新
const startAutoRefresh = () => {
  refreshInterval.value = setInterval(
    () => {
      // 使用当前选中的日期范围刷新数据
      if (dateRange.value && dateRange.value.length === 2) {
        const [start, end] = dateRange.value;
        fetchData(
          start instanceof Date ? start.toISOString().split("T")[0] : start,
          end instanceof Date ? end.toISOString().split("T")[0] : end
        );
      } else {
        // 如果没有选择日期范围，则使用默认的最近7天
        const [defaultStart, defaultEnd] = getLastSevenDays();
        fetchData(
          defaultStart.toISOString().split("T")[0],
          defaultEnd.toISOString().split("T")[0]
        );
      }
    },
    5 * 60 * 1000
  );
};

onMounted(() => {
  // 默认使用最近7天的数据
  const [defaultStart, defaultEnd] = getLastSevenDays();
  const startDateStr = defaultStart;
  const endDateStr = defaultEnd;

  // 设置初始日期范围并加载数据
  dateRange.value = [defaultStart, defaultEnd];
  fetchData(startDateStr, endDateStr);

  // 设置自动刷新
  startAutoRefresh();

  // 监控路由变化
  if (window.router) {
    const handleRouteChange = () => {
      nextTick(() => {
        handleResize();
      });
    };

    window.router.afterEach(handleRouteChange);
  }
});

onUnmounted(() => {
  // 清除 interval
  if (refreshInterval.value) {
    clearInterval(refreshInterval.value);
  }

  // 移除 resize listener
  window.removeEventListener("resize", handleResize);

  // 释放所有 charts
  disposeCharts();
});
</script>

<style lang="less">
.dashboard-container {
  padding: 24px;
  background-color: #f0f2f5;
  min-height: 100vh;

  // 头部区域样式
  .header-section {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 24px;
    background: white;
    padding: 16px 24px;
    border-radius: 12px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);

    .title-section {
      h2 {
        margin: 0;
        font-size: 24px;
        font-weight: 600;
        color: #303133;
      }

      .subtitle {
        color: #909399;
        font-size: 14px;
      }
    }

    .date-picker-section {
      .custom-date-picker {
        width: 360px;
      }
    }
  }

  // 统计卡片区域样式
  .stats-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 24px;
    margin-bottom: 24px;
  }

  .stat-card {
    background: linear-gradient(135deg, #fff 0%, #f8f9fa 100%);
    border-radius: 12px;
    padding: 24px;
    display: flex;
    align-items: center;
    transition: all 0.3s ease;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
    position: relative;
    overflow: hidden;

    &::before {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      height: 4px;
      background: var(--el-color-primary);
      opacity: 0;
      transition: opacity 0.3s ease;
    }

    &:hover {
      transform: translateY(-5px);
      box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.1);

      &::before {
        opacity: 1;
      }
    }

    .stat-icon {
      width: 48px;
      height: 48px;
      border-radius: 12px;
      background: var(--el-color-primary-light-9);
      display: flex;
      align-items: center;
      justify-content: center;
      margin-right: 16px;

      :deep(.el-icon) {
        font-size: 24px;
        color: var(--el-color-primary);
      }
    }

    .stat-content {
      flex: 1;

      .stat-title {
        color: #909399;
        font-size: 14px;
        margin: 0;
      }

      .stat-value {
        font-size: 24px;
        font-weight: bold;
        color: #303133;
        margin: 8px 0;
      }

      .stat-description {
        font-size: 12px;
        color: #909399;
      }
    }
  }

  // 中间部分
  .middle-section {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
    gap: 24px;
    margin-bottom: 24px;
  }

  // 底部部分
  .bottom-section {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
    margin-bottom: 24px;

    @media screen and (max-width: 1400px) {
      grid-template-columns: repeat(2, 1fr);
    }

    @media screen and (max-width: 1000px) {
      grid-template-columns: 1fr;
    }
  }

  // 图表卡片
  .chart-card {
    background: white;
    border-radius: 12px;
    padding: 20px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);

    .chart-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 16px;

      h3 {
        margin: 0;
        font-size: 16px;
        font-weight: 600;
        color: #303133;
      }
    }

    .chart {
      height: 300px;
    }
  }

  // 日志卡片
  .log-card {
    .log-list {
      height: 300px;
      overflow-y: auto;
      padding-right: 10px;

      .log-item {
        padding: 12px;
        border-bottom: 1px solid #ebeef5;
        font-size: 13px;
        display: flex;
        align-items: center;

        &:last-child {
          border-bottom: none;
        }

        .log-time {
          color: #909399;
          margin-right: 12px;
          white-space: nowrap;
        }

        .log-content {
          color: #606266;
          flex: 1;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }
    }
  }
}

// 响应式调整
@media screen and (max-width: 768px) {
  .dashboard-container {
    padding: 12px;

    .stats-cards {
      grid-template-columns: 1fr;
    }

    .middle-section,
    .bottom-section {
      grid-template-columns: 1fr;
    }

    .chart-card {
      .chart {
        height: 250px;
      }
    }
  }
}
</style>
